package com.globalwave.pos.sale.service;

import java.util.ArrayList;
import java.util.List;

import com.globalwave.base.BaseServiceImpl;
import com.globalwave.common.ArrayOrderList;
import com.globalwave.common.C;
import com.globalwave.pos.inventory.entity.ProductItem;
import com.globalwave.pos.inventory.entity.ProductItemSO;
import com.globalwave.pos.inventory.service.InventoryBO;
import com.globalwave.pos.sale.entity.SalesOrder;
import com.globalwave.pos.sale.entity.SalesOrderLine;



public class SalesOrderLineBO extends BaseServiceImpl{

	
	private SalesOrderLine line = null ;
	private InventoryBO inventoryBO = null ;
	private SalesOrderBO salesOrderBO = null ;

	public void add(ProductItem item, Integer quantity) throws Exception {
		
		SalesOrder order = salesOrderBO.getOrder() ;
		
		List<SalesOrderLine> lines = order.getLines() ;
		if (lines == null) {
			lines = new ArrayList<SalesOrderLine>() ;
			order.setLines(lines) ;
		}
		
		Long itemNumber = item.getItem_number() ;
		
		SalesOrderLine line = findNonMortgagedLine(lines, itemNumber) ;
		
		int salingQuantity = quantity ;
		if (line != null) {
			salingQuantity += line.getOrder_quantity() ;
		}
		
		ProductItemSO itemSo = new ProductItemSO() ;
		
		itemSo.setItem_number(itemNumber) ;
		itemSo.setOrder_quantity(salingQuantity) ;
		itemSo.setPrice_percentage(order.getPrice_percentage()) ;
		itemSo.setSale_date(order.getSale_date()) ;
		itemSo.setWarehouse_code(order.getWarehouse_code()) ;
		
		item = getInventoryBO().checkSalable(itemSo) ;// no exception is ok, continue;


		if (line == null) {
			line = newLine(order, item, quantity) ;
		} else {
			updateLine(line, item, quantity) ;
		}
		
		this.salesOrderBO.updateByLine(line, quantity) ;
	}
	
	private SalesOrderLine findNonMortgagedLine(List<SalesOrderLine> lines, Long itemNumber) {
		for (SalesOrderLine line:lines) {
			if (line.getId() != null) {// for order re-confirm
				continue ;
			}
			
			if(itemNumber.equals(line.getItem_number())) {
				return line ;
			}
		}
		
		
		return null ;
	}
	

	private SalesOrderLine newLine(SalesOrder order, ProductItem item, int quantity) {

		this.line = new SalesOrderLine() ;
		this.line.setLine_number(order.getLines().size()) ;
		order.getLines().add(this.line) ;
		this.line.setSalesOrder(order) ;
		
		this.line.setSale_date(order.getSale_date());
        //		   private String    type_               ;
		this.line.setItem_number(item.getItem_number()) ;
		this.line.setItem_sku(item.getItem_sku()) ;
		this.line.setStock_item_number(item.getStock_item_number()) ;
		this.line.setItem_desc(item.getShort_desc()) ;
		//this.line.setItem_class_code(item.get)
		this.line.setUnit_orginal_price(item.getOriginal_price()) ;
		this.line.setUnit_discount_price(item.getDiscount_price()) ;
		this.line.setUnit_price1(item.getPrice1()) ;
		this.line.setUnit_price2(item.getPrice2()) ;
		//this.line.setUnit_gift_point(item.get)
		this.line.setUnit_nation_tax(item.getNation_tax()) ;
		this.line.setUnit_location_tax(item.getLocation_tax()) ;
		this.line.setCurrency_code(item.getCurrency_code()) ;
		this.line.setUnit_code(item.getUnit_code()) ;
		this.line.setOrder_quantity(quantity) ;
		this.line.setReturned_quantity(C.ZERO_INTEGER) ;
		this.line.setShipped_quantity_total(C.ZERO_INTEGER) ;
		this.line.setShipped_quantity_1(C.ZERO_INTEGER) ;
		this.line.setShipped_quantity_2(C.ZERO_INTEGER) ;
		this.line.setShipped_quantity_3(C.ZERO_INTEGER) ;
		this.line.setShipped_quantity_4(C.ZERO_INTEGER) ;
		this.line.setShipped_quantity_5(C.ZERO_INTEGER) ;
		this.line.setTna_quantity(C.ZERO_INTEGER) ;
		
		//this.line.setReturnable_flag(item.getReturn_type()) ;
		//		   private String    promotion_code     ;
		//   private String    promotion_flag     ;
		this.line.setStatus_(C.STATUS_ACTIVE) ;
		
		return line ;
	}


	private void updateLine(SalesOrderLine line, ProductItem item, int quantity) {
		line.setOrder_quantity(line.getOrder_quantity() + quantity) ;
	}



	public void cancel()throws Exception  {
		this.line.setStatus_(C.STATUS_CANCEL) ;
	}
	
	public List<SalesOrderLine> getLines(Long orderId) throws Exception {
		SalesOrderLine so = new SalesOrderLine() ;
		so.setSales_order_id(orderId) ;
		
		ArrayOrderList orderList = new ArrayOrderList() ;
		orderList.add("line_number") ;
		
		return (List<SalesOrderLine>)this.jdbcDao.query(so, orderList, SalesOrderLine.class) ;
	}


	public void confirm(SalesOrderLine line) throws Exception {
		
		//line.setSales_order_id(line.getSalesOrder().getId()) ;
		this.getInventoryBO().mortgage(line) ;
		
		jdbcDao.insert(line) ;
	}


	public void ship(SalesOrderLine line, SalesOrderLine shipmentLine) throws Exception {
		
		int shipQuantity = shipmentLine.getShipped_quantity_total() ;
		int tnaQuantity = shipmentLine.getTna_quantity() ;
		
		if (shipQuantity == 0 && tnaQuantity == 0) {
			return ;
		}
		
		line.setShipped_quantity(shipQuantity)  ;
		line.setTna_quantity(tnaQuantity) ;
		//line.setShipped_quantity_total(line.getShipped_quantity_total() + shipQuantity) ;
		
		this.getInventoryBO().shipment(line) ;
		
		jdbcDao.update(line) ;
		
		this.salesOrderBO.updateByShipmentLine(shipmentLine) ;
	}
	


	public void autoShip(SalesOrderLine line) throws Exception  {
		//line.setShipped_quantity(line.getOrder_quantity()) ;
		line.setShipped_quantity_total(line.getOrder_quantity()) ;
	}
	
	public InventoryBO getInventoryBO() {
		if (this.inventoryBO == null) {
			inventoryBO = new InventoryBO();
			inventoryBO.setJdbcDao(jdbcDao) ;
		}
		return inventoryBO;
	}
	public void setInventoryBO(InventoryBO inventoryBO) {
		this.inventoryBO = inventoryBO;
	}


	public void setLine(SalesOrderLine line) {
		this.line = line;
	}
	
	public SalesOrderLine getLine() {
		return line;
	}

	public SalesOrderBO getSalesOrderBO() {
		return salesOrderBO;
	}

	public void setSalesOrderBO(SalesOrderBO salesOrderBO) {
		this.salesOrderBO = salesOrderBO;
	}

		
	
}
